﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KeyperDev
{
    class BackUp
    {
        private userList ul;
        private userInformation _ui;
        private user u =  new user();

        public BackUp(userList UL) 
        {
            ul = UL;
            _ui = new userInformation();
        }
        public int setBackupUser(string un) 
        {
            int i;
            int n = ul.userNum;
            for (i = 0; i < n; i++) 
            {
                if (String.Compare(((user)(ul.userArrayList[i])).userName, un) == 0) 
                {
                    u = ((user)(ul.userArrayList[i]));
                    break;
                }
            
            }
            if (i == n)
            {
                return -1;
            }
            else 
            {
                return 0;

            }
        
        }  //-1 表示无该用户

        public string DoBackup(string fileposition) 
        {
            _ui.u = u;
            _ui.readUserInfoFromFile();
            StringBuilder filenamestring = new StringBuilder();
            filenamestring.Clear();
            if (fileposition != null)
                filenamestring.Append(fileposition + @"\");
            DateTime dt = DateTime.Now;
            filenamestring.Append(stringTObase(_ui.u.userName) + "_" + dt.Year.ToString() + "_" + dt.Month.ToString() + "_" + dt.Day.ToString() +
                                    "_" + dt.Hour.ToString() + "_" + dt.Minute.ToString() + ".kpb");
            FileStream fs = File.Open(filenamestring.ToString(), FileMode.OpenOrCreate);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write((int)0);
            bw.Write(_ui.u.userName);
            bw.Write((int)-1);
            bw.Write(_ui.u.passwordHash);
            bw.Write(dt.Ticks);
            bw.Write(_ui.u.fp.useFP);
            if (_ui.u.fp.useFP == 1)
            {
                bw.Write(_ui.u.fp.RegAlready);
            }
            bw.Write((int)-2);
            bw.Write(_ui.pwRecords.passwordDic.Count);
            foreach (KeyValuePair<int, passwordRecord> kvp in _ui.pwRecords.passwordDic)
            {
                passwordRecord pr = (passwordRecord)(kvp.Value);
                bw.Write(pr.account);
                bw.Write(pr.date);
                bw.Write(pr.description);
                bw.Write(pr.encryptedPassword);
                bw.Write(pr.passwordEncryptionLevel);
                bw.Write(pr.passwordType);
                bw.Write(pr.pwortishi);
                bw.Write(pr.user);
                bw.Write((int)-3);
            }
            bw.Write((int)-4);
            bw.Close();
            fs.Close();
            return filenamestring.ToString();
        
        }
        public int PackIbfo(string filename)
        {
            int newuserflag = 0;
            FileStream fs = File.Open(filename, FileMode.OpenOrCreate);
            BinaryReader br = new BinaryReader(fs);
            string strtemp = "";
            int inttemp = -9;
            long longtemp = 0;
            inttemp = br.ReadInt32();
            userInformation uitemp = new userInformation();
            if (inttemp == 0)
            {
                strtemp = br.ReadString();
                uitemp.u.userName = strtemp;
                inttemp = br.ReadInt32();
                if (inttemp == -1)
                {
                    strtemp = br.ReadString();
                    uitemp.u.passwordHash = strtemp;
                    inttemp = br.ReadInt32();
                    longtemp = br.ReadInt64();

                }
                else
                {
                    return -1;
                }


            }
            else
            {
                return -1;

            }





            return 0;

        }
        public int DoRecovery(string filename) 
        {
            int newuserflag = 0;
            FileStream fs = File.Open(filename, FileMode.OpenOrCreate);
            BinaryReader br = new BinaryReader(fs);
            string strtemp = "";
            int inttemp = -9;
            long longtemp = 0;
            inttemp = br.ReadInt32();
            userInformation uitemp = new userInformation();
            uitemp.u.fp = new Fingerprint();
            if (inttemp == 0)
            {
                strtemp = br.ReadString();
                uitemp.u.userName = strtemp;
                inttemp = br.ReadInt32();
                if (inttemp == -1)
                {
                    strtemp = br.ReadString();
                    uitemp.u.passwordHash = strtemp;
                    longtemp = br.ReadInt64();
                    inttemp = br.ReadInt32();
                    if (inttemp == 1) 
                    {
                        uitemp.u.fp.useFP = 1;
                        uitemp.u.fp.RegAlready = br.ReadBytes(2048);
                    }
                    else if (inttemp == 0)
                    {
                        uitemp.u.fp.useFP = 0;

                    }
                    else 
                    {
                        br.Close();
                        fs.Close();
                        return -1;
                    }
                    inttemp = br.ReadInt32();
                    if (inttemp == -2)
                    {
                        inttemp = br.ReadInt32();
                        uitemp.pwRecords.recordsNum = inttemp;
                        int n = inttemp;
                        int i;
                        for (i = 0; i < n; i++) 
                        {
                            passwordRecord pr = new passwordRecord();
                            strtemp = br.ReadString();
                            pr.account = strtemp;
                            longtemp = br.ReadInt64();
                            pr.date = longtemp;
                            strtemp = br.ReadString();
                            pr.description = strtemp;
                            strtemp = br.ReadString();
                            pr.encryptedPassword = strtemp;
                            inttemp = br.ReadInt32();
                            pr.passwordEncryptionLevel = inttemp;
                            inttemp = br.ReadInt32();
                            pr.passwordType = inttemp;
                            inttemp = br.ReadInt32();
                            pr.pwortishi = inttemp;
                            strtemp = br.ReadString();
                            pr.user = strtemp;
                            inttemp = br.ReadInt32();
                            uitemp.pwRecords.passwordDic.Add(i,pr);
                            if (inttemp != -3) 
                            {
                                br.Close();
                                fs.Close();
                                return -1;
                            }

                            
                        }
                        inttemp = br.ReadInt32();
                        if (inttemp != -4) 
                        {
                            br.Close();
                            fs.Close();
                            return -1;
                        }
                        br.Close();
                        fs.Close();

                    }
                    else
                    {
                        br.Close();
                        fs.Close();
                        return -1;
                    
                    }
                }
                else
                {
                    br.Close();
                    fs.Close();
                    return -1;
                }


            }
            else
            {
                br.Close();
                fs.Close();
                return -1;

            }

            string backfilename = "";
            if (setBackupUser(uitemp.u.userName) == -1)
            {

                newuserflag = 1;
            }
            else 
            {
                newuserflag = 0;
                backfilename = DoBackup(null);
                //Directory.Delete(stringTObase(u.userName));
                if (Directory.Exists(stringTObase(u.userName) + @"\" + stringTObase("SecretRecord")))
                {///存在密码记录
                    ///密码记录处理部分
                    DirectoryInfo di = new DirectoryInfo(stringTObase(u.userName) + @"\" + stringTObase("SecretRecord"));
                    DirectoryInfo[] di2 = di.GetDirectories();
                    foreach (DirectoryInfo d in di2)
                    {
                        FileInfo[] inf = d.GetFiles();
                        foreach (FileInfo i in inf)
                        {
                            File.Delete(i.FullName);

                        }
                    }
                }
            }
            if (Directory.Exists(stringTObase(uitemp.u.userName)) == false)
                Directory.CreateDirectory(stringTObase(uitemp.u.userName));
            fs = File.Open(stringTObase(uitemp.u.userName) +@"\"+ stringTObase("finger"), FileMode.OpenOrCreate);
            BinaryWriter bw = new BinaryWriter(fs);
            if (uitemp.u.fp.useFP == 1)
            {
                bw.Write(1);
                bw.Write(uitemp.u.fp.RegAlready);
            }
            else 
            {
                bw.Write(0);
            }
            bw.Close();
            fs.Close();
            foreach (KeyValuePair<int, passwordRecord> kvp in uitemp.pwRecords.passwordDic)
            {
                passwordRecord pr = (passwordRecord)(kvp.Value);
                if (!Directory.Exists(stringTObase(uitemp.u.userName) + @"\" + stringTObase("SecretRecord")))
                {//首先判断路径是否存在
                    Directory.CreateDirectory(stringTObase(uitemp.u.userName) + @"\" + stringTObase("SecretRecord"));
                }
                if (!Directory.Exists(stringTObase(uitemp.u.userName) + @"\" + stringTObase("SecretRecord") + @"\" + stringTObase(pr.account)))
                {
                    Directory.CreateDirectory(stringTObase(uitemp.u.userName) + @"\" + stringTObase("SecretRecord") + @"\" + stringTObase(pr.account));
                }
                if (File.Exists(stringTObase(uitemp.u.userName) + @"\" + stringTObase("SecretRecord") + @"\" + stringTObase(pr.account) + @"\" + stringTObase(pr.user)))
                {
                    return -1;//已经有相同的密码记录存在
                }
                File.Create(stringTObase(uitemp.u.userName) + @"\" + stringTObase("SecretRecord") + @"\" + stringTObase(pr.account) + @"\" + stringTObase(pr.user)).Close();
                StreamWriter sw = new StreamWriter(stringTObase(uitemp.u.userName) + @"\" + stringTObase("SecretRecord") + @"\" + stringTObase(pr.account) + @"\" + stringTObase(pr.user), false);
                sw.WriteLine(pr.passwordType.ToString());
                sw.WriteLine(pr.passwordEncryptionLevel.ToString());
                sw.WriteLine(pr.account);
                sw.WriteLine(pr.user);
                sw.WriteLine(pr.encryptedPassword);
                sw.WriteLine(pr.description);
                DateTime dt = DateTime.Now;
                pr.date = dt.Ticks;
                sw.WriteLine(pr.date);
                sw.WriteLine(pr.pwortishi);
                sw.Close();
            }
            if (newuserflag == 1) 
            {
                if (!File.Exists("用户列表"))
                {
                    File.Create("用户列表").Close();
                }
                StreamWriter sw = new StreamWriter("用户列表", true);
                sw.WriteLine(uitemp.u.userName);
                sw.WriteLine(uitemp.u.passwordHash);
                sw.WriteLine("null");
                sw.Close();
            
            }



            return 0;
        
        }

        



#region
/*
        #region  本地备份/恢复
        public int backup(string fileposition) 
        {
            StringBuilder filenamestring = new StringBuilder();
            filenamestring.Clear();
            if (fileposition != null)
                filenamestring.Append(fileposition + @"\");
            DateTime dt = DateTime.Now;
            filenamestring.Append(stringTObase(u.userName)+"_"+dt.Year.ToString()+"_"+dt.Month.ToString()+"_"+dt.Day.ToString()+
                                    "_"+dt.Hour.ToString()+"_"+dt.Minute.ToString()+".kpb");
            FileStream fs = File.Open(filenamestring.ToString(), FileMode.OpenOrCreate);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write((int)0);
            bw.Write(u.userName);
            bw.Write((int)-1);
            bw.Write(u.passwordHash);
            bw.Write(dt.Ticks);
            bw.Write(u.fp.useFP);
            if (u.fp.useFP == 1) 
            {
                bw.Write(u.fp.RegAlready);
            }
            bw.Write((int)-2);
            bw.Write(pwRecords.recordsNum);
            foreach (KeyValuePair<int, passwordRecord> kvp in pwRecords.passwordDic)
            {
                passwordRecord pr = (passwordRecord)(kvp.Value);
                bw.Write(pr.account);
                bw.Write(pr.date);
                bw.Write(pr.description);
                bw.Write(pr.encryptedPassword);
                bw.Write(pr.passwordEncryptionLevel);
                bw.Write(pr.passwordType);
                bw.Write(pr.pwortishi);
                bw.Write(pr.user);
                bw.Write((int)-3);
            }
            bw.Write((int)-4);
            return 0;
        }

        public int recovery(string filename)  //0成功；-1 包损坏；
        {
            FileStream fs = File.Open(filename, FileMode.OpenOrCreate);
            BinaryReader br = new BinaryReader(fs);
            string strtemp = "";
            int inttemp = -9;
            inttemp = br.ReadInt32();
            userInformation uitemp = new userInformation();
            if (inttemp == 0)
            {
                strtemp = br.ReadString();
                uitemp.u.userName = strtemp;
                if (String.Compare(strtemp, u.userName) == 0) 
                {
                    
                }


            }
            else 
            {
                return -1;
            
            }





            return 0;
        }

        #endregion
 
 */
#endregion   

        private string baseTOstring(string st)
        {
            byte[] data;
            try
            {
                data = Convert.FromBase64String(st);
                return System.Text.ASCIIEncoding.Default.GetString(data);
            }
            catch
            {
                return st;
            }

        }
        public string stringTObase(string st)
        {
            byte[] data;
            try
            {
                System.Text.Encoding encode = System.Text.Encoding.UTF8;
                data = encode.GetBytes(st);
                return Convert.ToBase64String(data, 0, data.Length);
            }
            catch
            {
                return st;
            }
        }
    }


    /// <summary>
    /// int BuOrRec,int LocalOrOnline,userList ul,string filename,string username,string 
    /// </summary>
     public  class BackUpinfo 
    {
        public int BuOrRec = 0;
        public int LocalOrOnline = 0;
        public userList ul;
        public string filename = "";
        public string username = "";
        public string backupCode = "";
        public int result = 0;
    }
}
